#!/usr/bin/perl
#
# Richard Harvey 11/06/2008
# Version 0.6.1 beta
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
# e-mail:richard@squarecows.com

# Required Libraries

use HTTP::Request::Common qw(POST);
use LWP::UserAgent;
use Getopt::Std;
use YAML qw(Dump Bless);

# Variables

my $geoURL = "http://api.hostip.info/get_html.php";

# Get config file.

%options=();
getopts("c:h",\%options);
 our $config = $options{c};

# If you have a config file specified on the command line use it
if (defined($config)) {
 print "Using config file: $config\n";
# open default config file
 open(CFD, "$config");
 my $data = YAML::Load( join('',<CFD>) );
# Load the data YAML style
 our $log = $data->{apache_log};
 our $data_dir = $data->{data_dir};
 our $data_file = $data->{data_file};
 our $file = "$data_dir$data_file";
 our $icon = $data->{default_icon_color};
 our $new_icon = $data->{new_icon_color};
}
# If you don't have a specified config file use defaults Debian specific.
else {
 print "Using defaults\n";
 our $log = "/var/log/apache2/access.log";
 our $data_dir = "/var/www/";
 our $data_file = "data.xml";
 our $file = "$data_dir$data_file";
 our $icon = "blue";
 our $new_icon = "yellow";
}

if (-s $file) {

 print "Updating old markers in file: $file\n";

 open ( FILE, $file) or die "Cannot open file: $!";

 while ( $line = <FILE> ) {
# i is case insensative
# ([^>]*) match zero or more characters but not '>'
	$line =~ s/yellow/blue/i;
	push(@outLines, $line);
 }
 close FILE;

 open ( OUTFILE, ">$file" );
 print ( OUTFILE @outLines );
 close ( OUTFILE );



	my @iplist; # Declare an array to hold all IP addresses.
	open (FILE, "<:crlf", $log);

	print "Found old data adding new locations\n";
	open (FH, "+< $file") or die "can't update $file: $!";
	while ( <FH> ) {
    		$addr = tell(FH) unless eof(FH);
	}
	truncate(FH, $addr) or die "can't truncate $file: $!";
	open (MYFILE, ">>$file");
         
}
else {
	my @iplist; # Declare an array to hold all IP addresses.
	open (FILE, "<:crlf", $log);
	print "Creating new location data file\n";
	open (MYFILE, ">>$file");
	print MYFILE "<markers>\n";
}

# Parse Apache log

while (my $line=<FILE>) {
#	my ($ip_address,$date,$url_with_method,$status,$size,$referrer,$agent) = $line =~ m/^(\S+) - - \[(\S+ \+\d{4})\] "(\S+ \S+ [^"]+)" (\d{3}) (\d+|-) "(.*?)" "([^"]+)"$/;
#	Trying a patch suggested by Glen Carreras to support + and - timezones!
	my ($ip_address,$date,$url_with_method,$status,$size,$referrer,$agent) = $line =~ m/^(\S+) - - \[(\S+ [+|-]\d{4})\] "(\S+ \S+ [^"]+)" (\d{3}) (\d+|-) "(.*?)" "([^"]+)"$/;
	$url =~ s/\?(.*)//;
	$referrer=~ s/\?(.*)//;

	if($agent =~ m/iceweasel/i){
		$browser = "Iceweasel";
		$bicon = "iceweasel.png";
	}
	elsif($agent =~ m/Firefox/i){
		$browser = "Firefox";
		$bicon = "ff.png";
	}
	elsif($agent =~ m/MSIE/i){
		$browser = "Microsoft IE";
		$bicon = "ie.png";
	}
	elsif($agent =~ m/Safari/i){
		$browser = "Safari";	
		$bicon = "safari.png";
	}
	elsif($agent =~ m/Opera/i){
		$broswer = "Opera";
		$bicon = "opera.png";
	}
	elsif($agent =~ m/spider/o){
		$broswer = "spider";
		$bicon = "spider.png";
	}
	else{
		$browser = "Unknown";
		$bicon = "unknown.png";
	}

#print "$browser\n\n";

	push @iplist, ([$ip_address, $browser, $date, $bicon]);
}

# Process IP array and geo tag it

undef %saw;
#@out = grep(!$saw{$_}++, @iplist);

my $moo = 0;
my @out = ();
my %Seen   = ();

foreach (@iplist) {

	next if $Seen{ $_->[0] }++;
	push @out, ([$_->[0], $_->[1], $_->[2], $_->[3]]);
#	print "$_->[0]\n";


$moo++;
}

#my @out = grep { ! $seen{ $_ }++ } @iplist->[][0];


foreach (@out) {
my $ua=LWP::UserAgent->new();
my $req= POST $geoURL, [ "ip" => $_->[0] , "position" => "true" ];
$req->content_type('application/x-www-form-urlencoded');

#print "$_->[0] Agent: $_->[1]\n";

# Send Request
my $content=$ua->request($req)->as_string;

# Currenlty Rquired for error checking!
my $check=$ua->request($req);

if ($check->is_success) {
#print $content;

	my @co1 = split /Country: /, $content;
	my @co2 = split /\n/, @co1[1];
	my @ci1 = split /City: /, $content;
	my @ci2 = split /\n/, @ci1[1];
	my $country = @co2[0];
	my $city = @ci2[0];

# images section for country
	my @cc1 = split /\(/, $country;
	my @cc2 = split /\)/, @cc1[1];
	my $country_code= lc(@cc2[0]);
	if($country_code =~ m/unknown country?/i || $country_code =~ m/private address/i){
		$country_code = "none";
	}
#	print "$country_code\n";
	
		
	my @first = split /Latitude: /, $content;
#	print @first[1];

	my @second = split /Longitude: /, @first[1];

	my @third = split /\n/, @second[0];
	my $lat = @third[0];
	my @forth = split /\n/, @second[1];
	my $lon = @forth[0];
	if($lat) {
		 print MYFILE "<marker lat=\"$lat\" lng=\"$lon\" html=\"$country &lt;img src=&quot;./img/flags/$country_code.png&quot;&gt;&lt;br&gt;$city&lt;br&gt;Longitude: $lon&lt;br&gt;Latitude: $lat&lt;br&gt;Date: $_->[2]&lt;br&gt;Browser: $_->[1] &lt;img src=&quot;./img/browsericons/$_->[3]&quot; height=&quot;20&quot; width=&quot;20&quot; &gt;\" icon=\"$new_icon\"/>\n";
	}

}

}
print MYFILE "</markers>\n";

#close (FILE);
close (MYFILE);
#print @out;

# remove duplicate Locations!
if (-s $file) {
 my %seen = ();
 {
  local @ARGV = ($file);
  local $^I = '.bac';
   while(<>){
    $seen{$_}++;
    next if $seen{$_} > 1;
    print;
   }
 }
}

close (FILE);
#close (MYFILE);

print "Finished processing file.\n";
